package org.semanticflash.rdf.graph.redirection
{
	
	import flash.events.Event;
	
	import org.semanticflash.rdf.triple.RDFTriple;
	import org.semanticflash.rdf.values.IRI;
	import org.semanticflash.rdf.values.RDFValue;





	/**
	 *  
	 * Dispatched when "target" changes
	 * 
	 *  @eventType flash.events.Event.CHANGE
	 */
	[Event(name="change", type="flash.events.Event")]





	/**
	 * 
	 * 
	 * A triple can be redirected within the context of a graph.
	 * the Statement will observe the redirection for its triple
	 * to switch.
	 * 
	 * @author aldo.bucchi@gmail.com
	 * 
	 */
	public class RDFTripleRedirection extends AbstractRDFRedirection
	{




		
		private var _triple:RDFTriple;
		public function get triple( ):RDFTriple
		{
			return _triple;		
		}

		
		
		private var _target:RDFTriple;
		public function get target( ):RDFTriple
		{
			return _target;		
		}
		


		/**
		 * 
		 * 
		 * @param graph
		 * @param triple
		 * 
		 */
		public function RDFTripleRedirection( triple:RDFTriple, context:RDFRedirectionContext )
		{
			
			super( context );
			
			_triple = triple;
			
			_target = triple; // default redirection is to self
			
		
	
			if ( triple.s )
				modifyRedirectionListener( triple.s, true );
			
			if ( triple.p )
				modifyRedirectionListener( triple.p, true );
			
			if ( triple.o )
				modifyRedirectionListener( triple.o, true );

		}	
		
		
		private function onTermRedirectionChange( event:Event ):void
		{
			refresh( );
			
		}


		
		private function refresh( ):void
		{

			
			var newTarget:RDFTriple = RDFTriple.instance(
					  _context.cannonicalize( _triple.s )
					, _context.cannonicalize( _triple.p ) as IRI
					, _context.cannonicalize( _triple.o )
				);
				
			if ( _target === newTarget )
			{
				return;
			}
			
			_target = newTarget;

			dispatchEvent( new Event( Event.CHANGE ) );	
		
		}
		
		
		
		
		
		


		private function modifyRedirectionListener( term:RDFValue, subscribe:Boolean = true ):void
		{
			if ( ! term is IRI ) // only IRIs can be redirected
			{
				return;
			}
			
			var redirection:IRIRedirection = _context.getIRIRedirection( term as IRI );
			
			if ( subscribe )
				redirection.addEventListener( Event.CHANGE, onTermRedirectionChange );
			else
				redirection.removeEventListener( Event.CHANGE, onTermRedirectionChange );
			
		}
		



		
		
		
		


		
		
		
		
	}


}